package com.doubao.chat.service.impl;

import com.alibaba.fastjson.JSON;
import com.doubao.common.utils.RedisTemplateFactory;
import jakarta.annotation.PostConstruct;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import com.doubao.user.service.TokenService;
import com.doubao.common.result.Result;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * Token扣减处理服务
 * 定期处理待处理的token扣减记录
 */
@Component
@Slf4j
public class TokenProcessor {

    private RedisTemplate<String, Object> redisTemplate;

    @PostConstruct
    public void init() {
        this.redisTemplate = RedisTemplateFactory.getRedisTemplate();
        log.info("TokenProcessor使用RedisTemplateFactory获取RedisTemplate");
    }

    @Autowired
    private TokenService tokenService;

    /**
     * 定期处理待处理的token扣减记录
     * 每5分钟执行一次
     */
    @Scheduled(cron = "0 0 * * * *") // 每小时整点执行
    public void processPendingTokenDeductions() {
        log.info("开始处理待处理的 token 扣减记录...");
        String pendingDeductionsKey = "pending_token_deductions";
        int processedCount = 0;
        int failedCount = 0;
        int maxAttempts = 50; // 最多处理50条记录，避免长时间执行
        int attempts = 0;

        while (attempts++ < maxAttempts) {
            try {
                String deductionJson = (String) redisTemplate.opsForList().leftPop(pendingDeductionsKey);
                if (deductionJson == null) {
                    log.info("没有待处理的token扣减记录");
                    break; // No more pending deductions
                }

                Map<String, Object> deduction = JSON.parseObject(deductionJson);
                Long userId = Long.valueOf(deduction.get("userId").toString());
                Integer tokens = Integer.valueOf(deduction.get("tokens").toString());

                // 使用本地服务直接尝试扣减 token
                try {
                    Result<Void> result = tokenService.preDeductTokens(userId, tokens);
                    if (result.isSuccess()) {
                        log.info("成功处理 token 扣减: userId={}, tokens={}", userId, tokens);
                        processedCount++;
                    } else {
                        // 如果失败，推回队列
                        redisTemplate.opsForList().rightPush(pendingDeductionsKey, deductionJson);
                        log.warn("处理 token 扣减失败: userId={}, tokens={}, 错误: {}",
                                userId, tokens, result.getMessage());
                        failedCount++;
                        break; // 停止处理，避免无限循环处理问题记录
                    }
                } catch (Exception e) {
                    // 如果服务异常，推回队列
                    redisTemplate.opsForList().rightPush(pendingDeductionsKey, deductionJson);
                    log.error("调用 token 服务异常: userId={}, tokens={}, 错误: {}",
                            userId, tokens, e.getMessage());
                    failedCount++;
                    break;
                }
            } catch (Exception e) {
                log.error("处理 token 扣减记录时发生异常: {}", e.getMessage(), e);
                failedCount++;
            }
        }

        log.info("待处理 token 扣减处理完成: 成功={}, 失败={}", processedCount, failedCount);
    }
}